/**
 * 
 * @author Wouter, Jeroen
 *
 */

package com.eDriveV2;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

public class Processor extends Activity {

	private LocationManager locationManager;
	private LocationListener locationListener;
	private Location location;
	public TextView tv;
	private EcoCalculator ecoCalc;
	private XMLWriter xmlWriter;
	private HashMap<String, String> data;
	private int timeCounter;
	//private Button share;
	private File settingsFile;
	private Calendar c1;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		locationManager = (LocationManager) this
				.getSystemService(Context.LOCATION_SERVICE);
		tv = new TextView(this);
		c1 = new GregorianCalendar();
		c1.setTimeInMillis(System.currentTimeMillis());
		/*
		 * Checking if this is the first time the user launches the app. If so,
		 * create a new setting file with default setting. Else, find and open
		 * the existing setting file.
		 */
		// source:
		// http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
		// Check if external storage is available
		boolean mExternalStorageAvailable = false;
		boolean mExternalStorageWriteable = false;
		String state = Environment.getExternalStorageState();

		if (Environment.MEDIA_MOUNTED.equals(state)) {
			// We can read and write the media
			mExternalStorageAvailable = mExternalStorageWriteable = true;
		} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
			// We can only read the media
			mExternalStorageAvailable = true;
			mExternalStorageWriteable = false;
		} else {
			// Something else is wrong. It may be one of many other states, but
			// all we need
			// to know is we can neither read nor write
			mExternalStorageAvailable = mExternalStorageWriteable = false;
		}
		// end copy-paste
		if (mExternalStorageAvailable) {
			try {
				//settingsFile = new File(Environment.getExternalStorageDirectory()+"/eDriveData/settings.eDr");
				settingsFile = new File(Environment.getExternalStorageDirectory(), "eDriveData");
				if (!settingsFile.exists()) {
					settingsFile.mkdir();
				}
			} catch (NullPointerException e) {
				Log.d("File", "Weird err");
			}
			if (settingsFile.exists()) {
				Log.d("File", "Found settings file");
			} else {
				Log.e("File", "Cannot find file, tries to create one.");
				try {
					settingsFile.createNewFile();
				} catch (IOException e1) {
					Log.e("File",
							"Cannot create settings file! Gives IOException"
									+ e1.toString());
				}
				Log.e("File", "Succesfully created a new settings.txt");
				/*
				 * Fill settings.xml with default data/values
				 */
				try {
					setDefaultSettings(settingsFile);
				} catch (Exception e) {
					Log.e("Err",
							"Unknown error. Cannot create default values in settings: "
									+ e.toString());
				}
				// since this appears to be the first time the user opens the
				// app, show info/about screen
				showInfoScreen();
			}
			Log.e("File", "Settings file succesfully opened!");
		}
		data = new HashMap<String, String>();
		timeCounter = 0;
		locationListener = new LocationListener() {
			public void onLocationChanged(Location location) {
				int speedInt = (int) (location.getSpeed() * 3.6);
				// to avoid the little bug in the getSpeed() method
				// only show and save realistic speeds
				if (speedInt < 300) {
					ecoCalc.putSpeed(speedInt);
					setSpeedTextView(speedInt);
					Calendar c2 = new GregorianCalendar();
					c2.getInstance();
					long time = c2.getTimeInMillis() - c1.getTimeInMillis();
					data.put(
							"t" + timeCounter,
							String.valueOf(location.getLatitude() + ", "
									+ location.getLongitude() + ", " + speedInt
									+ ", " + EcoCalculator.testValue + ", "
									+ ecoCalc.getUberLabel() + ", " + time));
					timeCounter++;
					setEcoView(ecoCalc.getUberLabel());
				}
			}
			public void onProviderDisabled(String provider) {
				Toast.makeText(getApplicationContext(),
						"Warning! Gps is disabled! Please enable!", 10000)
						.show();
			}

			public void onProviderEnabled(String provider) {
				// do nothing
			}

			public void onStatusChanged(String provider, int status,
					Bundle extras) {
				// do nothing
			}
		};
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, locationListener);
		location = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		// Error checking: if above fails, then location == null. Quickfix.
		if (location == null) {
			location = new Location("GPS");
		}
		setContentView(R.layout.main);
		// all changes to textview's/etc. have to be done after setContentview.
		// otherwise null
		ecoCalc = new EcoCalculator();
	}

	/**
	 * Update the GUI with the given efficiency
	 * 
	 * @param label
	 *            , String
	 */
	public void setEcoView(String labels) {
		ImageView MyEcoView = (ImageView) findViewById(R.id.ecoImageView);
		if (labels == "?") {
			MyEcoView.setImageResource(R.drawable.label);
		} else if (labels == "A") {
			MyEcoView.setImageResource(R.drawable.label_a);
		} else if (labels == "B") {
			MyEcoView.setImageResource(R.drawable.label_b);
		} else if (labels == "C") {
			MyEcoView.setImageResource(R.drawable.label_c);
		} else if (labels == "D") {
			MyEcoView.setImageResource(R.drawable.label_d);
		} else if (labels == "E") {
			MyEcoView.setImageResource(R.drawable.label_e);
		} else if (labels == "F") {
			MyEcoView.setImageResource(R.drawable.label_f);
		} else if (labels == "G") {
			MyEcoView.setImageResource(R.drawable.label_g);
		} else if (labels == "Error") {
			MyEcoView.setImageResource(R.drawable.label);
		} else {
			MyEcoView.setImageResource(R.drawable.label);
		}
	}

	/**
	 * Update the GUI with the given speed.
	 * 
	 * @param speed
	 *            , String
	 */
	public void setSpeedTextView(String speed) {
		TextView tv = (TextView) findViewById(R.id.speedTextView);
		tv.setText(speed + " km/h");
	}

	/**
	 * Update the GUI with the given speed.
	 * 
	 * @param speed
	 *            , int
	 */
	public void setSpeedTextView(int speed) {
		setSpeedTextView(String.valueOf(speed));
	}

	/*
	 * Method which is called when user clicks the 'write to XML' button.
	 */
	public void stopRecording(View v) {
		Log.d("Lenght data:", String.valueOf(data.size()));
		if (data.size() == 0) {
			Log.d("TEST", "No data in hashmap");
			Toast.makeText(getApplicationContext(), "No data to save.", 10).show();
			return;
		}
		xmlWriter = new XMLWriter();
		xmlWriter.writeToFile(data);
	}

	/*
	 * Onclick method for the share button. Opens a generated 'share menu',
	 * builtin in Android reads the avg efficiency and passes it on to the
	 * selected application for sharing
	 */
	public void shareButton(View v) {
		String values = ecoCalc.calculateAvgEfficiency();

		String values2 = "";
		if (values.equals("A")) {
			values2 = "Look how I care for the environment! \n"
					+ " I just drove label: " + values;
		} else if (values.equals("B")) {
			values2 = "Look how I care for the environment.\n"
					+ "I just drove label: " + values + "\n"
					+ "It is not perfect, but I'm getting there";
		} else if (values.equals("C")) {
			values2 = "Look how I care for the environment.\n"
					+ " I just drove label: " + values + "\n"
					+ "But there is still a lot to improve";
		} else if (values.equals("D")) {
			values2 = "I need to care more for the environment, but I'm getting there.\n"
					+ " i just drove label: " + values;
		} else if (values.equals("E")) {
			values2 = "I need to care more for the environment, but I'm slowly getting there.\n"
					+ " i just drove label: " + values;
		} else if (values.equals("F")) {
			values2 = "I need to care more for the environment.\n"
					+ " I just drove label: " + values;
		} else if (values.equals("G")) {
			values2 = "I need to care more for the environment.\n"
					+ " I just drove label: " + values;
		}
		else{
			values2 = "Error. eDrive could not retrieve the efficiency of this ride.\n";
		}
		Log.d("Test:", "Begin shareButton()");
		Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
		emailIntent.setType("text/plain");
		String Subject = "Edrive";
		emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, (Subject));
		emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, values2);
		startActivity(emailIntent);
	}

	public void readXML(View v) {
		Log.d("Test:", "Begin reading XML()");
		Intent filereadIntent = new Intent(Processor.this, XMLReader.class);

		startActivity(filereadIntent);
	}

	/*
	 * Method to automatically write default settings to the settings file for
	 * now. Can be expanded for use with multiple files.
	 */
	public void setDefaultSettings(File f) throws IOException {
		FileWriter fw = new FileWriter(f);
		fw.write("Settings for eDrive. Do not manually edit!\n");
		fw.write("firstTime: true");
		Log.d("SettingsFile", "Succesfully written to settings file.");
		fw.close();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.settingsItem:
				showSettings();
				return true;
			case R.id.statViewItem:
				showFileOverview();
				return true;
			case R.id.helpItem:
				showInfoScreen();
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}

	/*
	 * Method called by pressing 'Settings' in the options menu. Opens the
	 * settings window.
	 */
	private void showSettings() {
		Toast.makeText(getApplicationContext(),
				"Currently no settings available", 15).show();
	}

	private void showStatView(View v) {
		Intent myIntent = new Intent(v.getContext(), Statview.class);
		startActivityForResult(myIntent, 0);
	}

	/*
	 * Show the infoscreen in an PopupWindow.
	 */
	private void showInfoScreen() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(R.string.infoText)
				.setCancelable(false)
				.setNegativeButton("Close",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});
		AlertDialog alert = builder.create();
		alert.show();
	}
	/*
	 * Start the fileOverview activity after pressing the menu item in the
	 * options menu
	 */
	private void showFileOverview() {
		Intent fileOverviewIntent = new Intent(Processor.this,
				FileOverview.class);

		startActivity(fileOverviewIntent);
	}
	private void showMaps() {
		Intent mapsOverview = new Intent(Processor.this, MapViewer.class);
		startActivity(mapsOverview);
	}
}